package com.tutu.flow.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.RepositoryServiceImpl;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmActivity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.impl.pvm.process.TransitionImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.tutu.flow.service.IModelRollBackSerivce;

@Service("modelRollBackSerivce")
public class ModelRollBackSerivceImpl implements IModelRollBackSerivce {

	protected Logger logger = LoggerFactory.getLogger(getClass());
	
	@Resource
	private RuntimeService runtimeService;
	@Resource
	private TaskService taskService;
	@Resource
	private RepositoryService repositoryService;
	@Resource
	private HistoryService historyService;
	
	@Override
	public void rollBackWorkFlow(String taskId) throws Exception {
		HistoricTaskInstance historicTaskInstance = this.historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
		ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
		if(null == processInstance){
			logger.error("流程已结束");
			return;
		}
		Map<String, Object> variables = processInstance.getProcessVariables();
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) this.repositoryService).getDeployedProcessDefinition(historicTaskInstance.getProcessDefinitionId());
		if(null == processDefinitionEntity){
			logger.error("未找到流程定义");
		}
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(historicTaskInstance.getTaskDefinitionKey());
//		上一节点连线
		List<PvmTransition> lastTransitions = activityImpl.getIncomingTransitions();
//		下一节点连线
		List<PvmTransition> nextTransitions = activityImpl.getOutgoingTransitions();
//		保存下节点连线
		List<PvmTransition> outTransitions = new ArrayList<PvmTransition>();
		outTransitions.addAll(nextTransitions);
		nextTransitions.clear();
//		新的目的地
		List<TransitionImpl> newTransitionImpls = new ArrayList<TransitionImpl>();
		for(PvmTransition lastTransition : lastTransitions){
			PvmActivity sourceActivity = lastTransition.getSource();
			ActivityImpl sourceActivityImpl = processDefinitionEntity.findActivity(sourceActivity.getId());
			TransitionImpl transitionImpl = activityImpl.createOutgoingTransition();
			transitionImpl.setDestination(sourceActivityImpl);
			newTransitionImpls.add(transitionImpl);
		}
//		执行任务
		List<Task> tasks = this.taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(historicTaskInstance.getTaskDefinitionKey()).list();
		for(Task task : tasks){
			this.taskService.complete(task.getId(), variables);
			this.historyService.deleteHistoricTaskInstance(task.getId());
		}
//		还原流转
		for(TransitionImpl transitionImpl : newTransitionImpls){
			activityImpl.getOutgoingTransitions().remove(transitionImpl);
		}
		nextTransitions.addAll(outTransitions);
	}

	@Override
	public void rollBackToAssignWorkFlow(String taskId, String destTaskKey)
			throws Exception {
		HistoricTaskInstance historicTaskInstance = this.historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
		ProcessInstance processInstance = this.runtimeService.createProcessInstanceQuery().processInstanceId(historicTaskInstance.getProcessInstanceId()).singleResult();
		if(null == processInstance){
			logger.error("流程已结束");
			return;
		}
		Map<String, Object> variables = processInstance.getProcessVariables();
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) this.repositoryService).getDeployedProcessDefinition(historicTaskInstance.getProcessDefinitionId());
		if(null == processDefinitionEntity){
			logger.error("未找到流程定义");
		}
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(historicTaskInstance.getTaskDefinitionKey());
//		上一节点连线
		List<PvmTransition> lastTransitions = activityImpl.getIncomingTransitions();
//		下一节点连线
		List<PvmTransition> nextTransitions = activityImpl.getOutgoingTransitions();
//		保存下节点连线
		List<PvmTransition> outTransitions = new ArrayList<PvmTransition>();
		outTransitions.addAll(nextTransitions);
		nextTransitions.clear();
//		新的目的地
		List<TransitionImpl> newTransitionImpls = new ArrayList<TransitionImpl>();
		for(PvmTransition lastTransition : lastTransitions){
			ActivityImpl sourceActivityImpl = processDefinitionEntity.findActivity(destTaskKey);
			TransitionImpl transitionImpl = activityImpl.createOutgoingTransition();
			transitionImpl.setDestination(sourceActivityImpl);
			newTransitionImpls.add(transitionImpl);
		}
//		执行任务
		List<Task> tasks = this.taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(historicTaskInstance.getTaskDefinitionKey()).list();
		for(Task task : tasks){
			this.taskService.complete(task.getId(), variables);
			this.historyService.deleteHistoricTaskInstance(task.getId());
		}
//		还原流转
		for(TransitionImpl transitionImpl : newTransitionImpls){
			activityImpl.getOutgoingTransitions().remove(transitionImpl);
		}
		nextTransitions.addAll(outTransitions);
		
	}

	
}
